/**********************************************************
If the input is void, generate a param file

*****************************************************************/

using namespace std;


//allow use of global variables 

extern float maxtime;     
extern float timestep;    
extern float galaxy_sfr;  
extern string model_name;
extern string imf_type;
extern string galaxy_sfh;  
extern double max_cluster_mass;  
extern double slope_cmf;         
extern double min_cluster_mass;  
extern string drawtype;  
extern time_t seed;
extern long bincolor;
extern long binflux;
extern string outcluster;
extern string imfout;
extern double imf_slope;
extern string libpath;
extern double clust_frac;
extern double log_time;
extern double clust_disrupt;

void parse_param(int argc, char *argv[]){

#ifndef QUIET  
  //some greetings.
  cout<<"************************************************"<<endl;
  cout<<"*                                              *"<<endl;
  cout<<"* SLUG: Stochastically Light Up Galaxies       *"<<endl;
  cout<<"*                                              *"<<endl;
  cout<<"* Visit https://sites.google.com/site/runslug/ *"<<endl;
  cout<<"************************************************"<<endl<<endl<<endl;
  
#endif /* QUIET */

  //if the par file is set, parse it
  if(argc == 2) {
    

    string line,extr,par;
    size_t f1,f2;
    string outflux;  
    string outcolor;  
    string outminflux;  
    string outmincolor;  
    string outmaxflux;  
    string outmaxcolor;  
    
    //first, set all the variables to their default values 
    //so that if a entry is missing in the parfile the code
    //sets them to their default 
    timestep=(float) 2E6;    
    maxtime=(float) 1E9;     
    log_time=(double) 0;
    galaxy_sfr=(float) 1.0;  
    galaxy_sfh.assign("mysfh.txt");  
    imf_type.assign("KROUPA");
    imf_slope=(double) -2.35;
    libpath.assign("iso/padagb/020/lej+smi/maedr/");
    model_name.assign("SLUG_DEF");
    max_cluster_mass=(double) 1E7;  
    min_cluster_mass=(double) 20.;  
    slope_cmf=(double) -2.0;         
    clust_frac=(double) 1.0;
    clust_disrupt=(double) 1.0;
    drawtype.assign("RANDOM"); 
    seed=(time_t) 0;
    outflux.assign("FUV,QH0");
    outcolor.assign("FUV-QH0");
    binflux=(long) 2;
    bincolor=(long) 2;
    outmaxcolor.assign("20");
    outmincolor.assign("1");  
    outmaxflux.assign("50");  
    outminflux.assign("1");  
    outcluster.assign("no");
    imfout.assign("no");
    
    
    //open to read
    ifstream myfile (argv[1]);
    if (myfile.is_open())
      {
	while (! myfile.eof() )
	  {
	    getline (myfile,line);
	    
	    //drop comments line
	    f1=line.find("#");
	    if(f1 != 0){ 
	      
	    //timestep 
	      par.assign("timestep");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		timestep=atof(extr.data());
	      }
	      
	      //maxtime
	      par.assign("maxtime");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		maxtime=atof(extr.data());	
	      }
	      
	      //log_time
	      par.assign("log_time");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		log_time=(double) atof(extr.data());	
	      }
	      
	      //galaxy_sfr
	      par.assign("galaxy_sfr");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		galaxy_sfr=atof(extr.data());
	      }
	      
	      //galaxy SFH
	      par.assign("galaxy_sfh");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		galaxy_sfh=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=galaxy_sfh.find_first_not_of(" \t");
		size_t endpos=galaxy_sfh.find_last_not_of(" \t"); 
		galaxy_sfh=galaxy_sfh.substr(startpos,endpos-startpos+1);
	      }
	      
	      //model name
	      par.assign("model_name");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		model_name=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=model_name.find_first_not_of(" \t");
		size_t endpos=model_name.find_last_not_of(" \t"); 
		model_name=model_name.substr(startpos,endpos-startpos+1);
	      }
	      
	      //IMF
	      par.assign("imf_type");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		imf_type=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=imf_type.find_first_not_of(" \t");
		size_t endpos=imf_type.find_last_not_of(" \t"); 
		imf_type=stringconversion(imf_type.substr(startpos,endpos-startpos+1),0);
	      }	    
	
	      //IMF SLOPE
	      par.assign("imf_slope");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		imf_slope=atof(extr.data());
	      }
	    
	      
	      //path to stellar libraries
	      par.assign("libpath");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		libpath=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=libpath.find_first_not_of(" \t");
		size_t endpos=libpath.find_last_not_of(" \t"); 
		libpath=libpath.substr(startpos,endpos-startpos+1);
	      }	    


	      //min cluster mass
	      par.assign("min_cluster_mass");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		min_cluster_mass=atof(extr.data());
	      }
	      
	      //max cluster mass
	      par.assign("max_cluster_mass");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		max_cluster_mass=atof(extr.data());
	      }
	      
	      
	      //slope cmf
	      par.assign("slope_cmf");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		slope_cmf=atof(extr.data());
	      }
	      
	      //fraction clustered star 
	      par.assign("clust_frac");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		clust_frac=atof(extr.data());
	      }
	      //parameter controlling the disruption of clusters
              par.assign("clust_disrupt");
              f1=line.find(par.data());
              f2=line.find("#");
              if (f1!=string::npos){
                extr=line.substr(f1+par.size(),f2-f1-par.size());
                clust_disrupt=atof(extr.data());
              }


	      //draw type
	      par.assign("drawtype");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		drawtype=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=drawtype.find_first_not_of(" \t");
		size_t endpos=drawtype.find_last_not_of(" \t"); 
		drawtype=stringconversion(drawtype.substr(startpos,endpos-startpos+1),0);
	      }	    
	        
	      //seed
	      par.assign("seed");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		seed=(time_t)atof(extr.data());
	      }
	    
	      //color
	      par.assign("colors");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		outcolor=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=outcolor.find_first_not_of(" \t");
		size_t endpos=outcolor.find_last_not_of(" \t"); 
		 if (startpos != endpos){
		   outcolor=stringconversion(outcolor.substr(startpos,endpos-startpos+1),0);
		 } else outcolor="none";
	      }	    
	      
	      //flux
	      par.assign("fluxes");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		outflux=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=outflux.find_first_not_of(" \t");
		size_t endpos=outflux.find_last_not_of(" \t"); 
		outflux=stringconversion(outflux.substr(startpos,endpos-startpos+1),0);
	      }	    
	    
	      
	      //bin in flux
	      par.assign("binflux");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		binflux=(long)atof(extr.data());
	      }

	      //bin in color
	      par.assign("bincolor");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		extr=line.substr(f1+par.size(),f2-f1-par.size());
		bincolor=(long)atof(extr.data());
	      }

	      //minflux
	      par.assign("minflux");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		outminflux=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=outminflux.find_first_not_of(" \t");
		size_t endpos=outminflux.find_last_not_of(" \t"); 
		outminflux=outminflux.substr(startpos,endpos-startpos+1);
	      }	    
	    
	      //maxflux
	      par.assign("maxflux");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		outmaxflux=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=outmaxflux.find_first_not_of(" \t");
		size_t endpos=outmaxflux.find_last_not_of(" \t"); 
		outmaxflux=outmaxflux.substr(startpos,endpos-startpos+1);
	      }	    

	      //mincolor
	      par.assign("mincolor");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		outmincolor=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=outmincolor.find_first_not_of(" \t");
		size_t endpos=outmincolor.find_last_not_of(" \t"); 
		outmincolor=outmincolor.substr(startpos,endpos-startpos+1);
	      }	    
	      
	      //maxcolor
	      par.assign("maxcolor");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		outmaxcolor=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=outmaxcolor.find_first_not_of(" \t");
		size_t endpos=outmaxcolor.find_last_not_of(" \t"); 
		outmaxcolor=outmaxcolor.substr(startpos,endpos-startpos+1);
	      }	    

	      //enable disable output cluster file
	      par.assign("outcluster");
	      f1=line.find(par.data());
	      f2=line.find("#");
	      if (f1!=string::npos){
		outcluster=line.substr(f1+par.size(),f2-f1-par.size());
		//Trim leading and trailing spaces
		size_t startpos=outcluster.find_first_not_of(" \t");
		size_t endpos=outcluster.find_last_not_of(" \t"); 
		outcluster=stringconversion(outcluster.substr(startpos,endpos-startpos+1),1);
	      }	    
	       //enable disable output imf file
              par.assign("imfout");
              f1=line.find(par.data());
              f2=line.find("#");
              if (f1!=string::npos){
                imfout=line.substr(f1+par.size(),f2-f1-par.size());
                //Trim leading and trailing spaces
                size_t startpos=imfout.find_first_not_of(" \t");
                size_t endpos=imfout.find_last_not_of(" \t");
                imfout=stringconversion(imfout.substr(startpos,endpos-startpos+1),1);
              }

	    }//close drop comment line
	    
	  }
	myfile.close();

    }
    
    else cout << "Unable to open .param file. Use def..."; 

#ifndef QUIET
   
    //Tell the user what par are you actually using. Freedom is associated with 
    //responsability, but I'm the first one that forgets things.
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
    cout<<"SLUG is running with the following parameters"<<endl;
    cout<<"\t"<<"timestep: "<<timestep<<endl;
    cout<<"\t"<<"maxtime: "<<maxtime<<endl;
    cout<<"\t"<<"log_time: "<<log_time<<endl;
    cout<<"\t"<<"galaxy_sfr: "<<galaxy_sfr<<endl;
    cout<<"\t"<<"galaxy_sfh: "<<galaxy_sfh<<endl;
    cout<<"\t"<<"imf_type: "<<imf_type<<endl;
    cout<<"\t"<<"imf_slope: "<<imf_slope<<endl;
    cout<<"\t"<<"libpath: "<<libpath<<endl;
    cout<<"\t"<<"model_name: "<<model_name<<endl;
    cout<<"\t"<<"max_cluster_mass: "<<max_cluster_mass<<endl;
    cout<<"\t"<<"min_cluster_mass: "<<min_cluster_mass<<endl;
    cout<<"\t"<<"slope_cmf: "<<slope_cmf<<endl;
    cout<<"\t"<<"clust_frac: "<<clust_frac<<endl;
    cout<<"\t"<<"clust_disrupt: "<<clust_disrupt<<endl;
    cout<<"\t"<<"drawtype: "<<drawtype<<endl; 
    cout<<"\t"<<"seed: "<<seed<<endl;
    cout<<"\t"<<"fluxes: "<<outflux<<endl;
    cout<<"\t"<<"colors: "<<outcolor<<endl;
    cout<<"\t"<<"binflux: "<<binflux<<endl;
    cout<<"\t"<<"bincolor: "<<bincolor<<endl;
    cout<<"\t"<<"maxcolor: "<<outmaxcolor<<endl;
    cout<<"\t"<<"mincolor: "<<outmincolor<<endl;
    cout<<"\t"<<"maxflux: "<<outmaxflux<<endl;
    cout<<"\t"<<"minflux: "<<outminflux<<endl;
    cout<<"\t"<<"outcluster: "<<outcluster<<endl;
    cout<<"\t"<<"imfout: "<<imfout<<endl;
    cout<<"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"<<endl;
    
#endif /* QUIET */

    //call function that parse the colors and fluxes
    //now we know the fluxes we want and allocate the global variables
    histo_initialise(outflux,outcolor,outminflux,outmaxflux,outmincolor,outmaxcolor);
    
  } else generate_param(); //if not, make a default
  
  return;
}
